from PySide6.QtWidgets import (
    QWidget, QPushButton, QLabel, QSlider,
    QTextEdit, QVBoxLayout, QHBoxLayout
)
from PySide6.QtCore import Qt, QPoint, Signal, Property, QSize
from PySide6.QtGui import QMouseEvent, QPalette, QColor, QFont

class DraggableComponent(QWidget):
    """可拖动组件的基类"""
    # 自定义信号
    position_changed = Signal(str, int, int)  # 组件ID，x坐标，y坐标
    lock_changed = Signal(str, bool)  # 组件ID，锁定状态
    
    def __init__(self, component_id, parent=None):
        super().__init__(parent)
        self.component_id = component_id
        self.locked = False
        self.dragging = False
        self.drag_start_position = QPoint()
        
        # 设置无边框窗口
        self.setWindowFlags(Qt.WindowType.FramelessWindowHint)
        
        # 设置样式 - 添加阴影和更清晰的边框
        self.setStyleSheet("""
            QWidget {
                background-color: #f8f8f8;
                border: 2px solid #cccccc;
                border-radius: 6px;
            }
        """)
        
        # 启用样式表
        self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True)
        
        # 初始布局 - 增加内边距
        self.layout = QVBoxLayout(self)
        self.layout.setContentsMargins(12, 12, 12, 12)
        self.layout.setSpacing(12)
        
        # 标题栏（用于拖动）
        self.header = QWidget()
        self.header.setStyleSheet("background-color: #e0e0e0; border-radius: 4px; border: none;")
        self.header.setMinimumHeight(30)  # 确保标题栏高度足够
        self.header_layout = QHBoxLayout(self.header)
        self.header_layout.setContentsMargins(10, 5, 10, 5)
        
        # 标题和锁定图标
        self.title_label = QLabel(component_id)
        title_font = QFont()
        title_font.setBold(True)
        title_font.setPointSize(11)
        self.title_label.setFont(title_font)
        self.title_label.setStyleSheet("border: none;")
        self.title_label.setMinimumWidth(150)  # 增加标题最小宽度确保文字完整显示
        self.title_label.setMaximumHeight(20)  # 限制标题高度
        self.title_label.setWordWrap(False)    # 防止标题换行
        self.title_label.setAlignment(Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter)
        
        # 锁定状态指示标签
        self.lock_indicator = QLabel("🔓")
        self.lock_indicator.setStyleSheet("border: none; font-size: 16px;")
        self.lock_indicator.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
        self.lock_indicator.setCursor(Qt.CursorShape.PointingHandCursor)
        self.lock_indicator.setMinimumWidth(30)  # 确保锁定图标有足够空间
        self.lock_indicator.mousePressEvent = self.toggle_lock
        
        self.header_layout.addWidget(self.title_label, 4)  # 增大标题占用空间比例
        self.header_layout.addWidget(self.lock_indicator, 0)
        
        self.layout.addWidget(self.header)
        
        # 添加分隔线
        separator = QWidget()
        separator.setFixedHeight(1)
        separator.setStyleSheet("background-color: #dddddd; border: none;")
        self.layout.addWidget(separator)
        
        # 内容容器 - 增加内边距，确保内容有足够空间
        self.content = QWidget()
        self.content.setStyleSheet("border: none; background-color: transparent;")
        self.content_layout = QVBoxLayout(self.content)
        self.content_layout.setContentsMargins(8, 10, 8, 10)
        self.content_layout.setSpacing(12)
        self.layout.addWidget(self.content)
        
        # 设置最小尺寸以确保组件不会太小
        self.setMinimumSize(220, 120)
    
    def sizeHint(self):
        """提供默认的尺寸建议"""
        return QSize(250, 150)
    
    def mousePressEvent(self, event: QMouseEvent):
        """鼠标按下事件"""
        if event.button() == Qt.MouseButton.LeftButton and not self.locked:
            # 仅当点击标题栏区域时才允许拖动
            if self.header.geometry().contains(event.position().toPoint()):
                self.dragging = True
                self.drag_start_position = event.position().toPoint()
                self.setCursor(Qt.CursorShape.SizeAllCursor)
        super().mousePressEvent(event)
    
    def mouseMoveEvent(self, event: QMouseEvent):
        """鼠标移动事件"""
        if self.dragging and not self.locked:
            delta = event.position().toPoint() - self.drag_start_position
            new_pos = self.pos() + QPoint(delta.x(), delta.y())
            self.move(new_pos)
            # 发射位置改变信号
            self.position_changed.emit(self.component_id, new_pos.x(), new_pos.y())
        super().mouseMoveEvent(event)
    
    def mouseReleaseEvent(self, event: QMouseEvent):
        """鼠标释放事件"""
        if event.button() == Qt.MouseButton.LeftButton and self.dragging:
            self.dragging = False
            self.setCursor(Qt.CursorShape.ArrowCursor)
        super().mouseReleaseEvent(event)
    
    def toggle_lock(self, event=None):
        """切换锁定状态"""
        self.locked = not self.locked
        self.update_lock_indicator()
        # 发射锁定状态改变信号
        self.lock_changed.emit(self.component_id, self.locked)
    
    def update_lock_indicator(self):
        """更新锁定状态指示器"""
        if self.locked:
            self.lock_indicator.setText("🔒")
            # 设置背景颜色为浅红色表示锁定
            self.header.setStyleSheet("background-color: #ffdddd; border-radius: 4px; border: none;")
        else:
            self.lock_indicator.setText("🔓")
            # 恢复默认背景颜色
            self.header.setStyleSheet("background-color: #e0e0e0; border-radius: 4px; border: none;")
    
    def set_locked(self, locked):
        """设置锁定状态"""
        self.locked = locked
        self.update_lock_indicator()


class ButtonComponent(DraggableComponent):
    """按钮组件"""
    button_clicked = Signal(str)  # 按钮ID
    
    def __init__(self, component_id, text, parent=None):
        super().__init__(component_id, parent)
        self.title_label.setText(f"按钮: {component_id}")
        
        # 设置按钮的最小尺寸确保完整显示
        self.setMinimumSize(200, 140)
        
        # 确保内容区域足够大
        self.content.setMinimumHeight(80)
        
        # 添加按钮 - 增大按钮尺寸
        self.button = QPushButton(text)
        self.button.setMinimumSize(160, 60)
        self.button.setStyleSheet("""
            QPushButton {
                font-size: 14px;
                font-weight: bold;
                padding: 10px;
                background-color: #0078d7;
                color: white;
                border-radius: 5px;
                border: none;
                margin: 5px;
            }
            QPushButton:hover {
                background-color: #1089e8;
            }
            QPushButton:pressed {
                background-color: #005fa3;
            }
        """)
        self.button.setCursor(Qt.CursorShape.PointingHandCursor)
        self.button.clicked.connect(lambda: self.button_clicked.emit(self.component_id))
        self.content_layout.addWidget(self.button)
    
    def sizeHint(self):
        """提供按钮组件的默认尺寸建议"""
        return QSize(200, 140)


class TextDisplayComponent(DraggableComponent):
    """文本显示组件"""
    def __init__(self, component_id, text, parent=None):
        super().__init__(component_id, parent)
        self.title_label.setText(f"文本显示: {component_id}")
        
        # 设置文本显示组件的最小尺寸
        self.setMinimumSize(260, 220)
        
        # 确保内容区域足够大
        self.content.setMinimumHeight(150)
        
        # 容器布局
        container = QWidget()
        container.setStyleSheet("background-color: transparent; border: none;")
        container_layout = QVBoxLayout(container)
        container_layout.setContentsMargins(0, 0, 0, 0)
        
        # 添加文本显示框 - 增大文本框尺寸
        self.text_display = QTextEdit()
        self.text_display.setReadOnly(True)
        self.text_display.setText(text)
        self.text_display.setMinimumSize(230, 140)
        self.text_display.setStyleSheet("""
            QTextEdit {
                font-size: 14px;
                line-height: 150%;
                border: 1px solid #cccccc;
                border-radius: 4px;
                background-color: white;
                padding: 10px;
                margin: 5px;
            }
        """)
        container_layout.addWidget(self.text_display)
        
        # 添加容器到内容布局
        self.content_layout.addWidget(container)
    
    def set_text(self, text):
        """设置显示文本"""
        self.text_display.setText(text)
    
    def sizeHint(self):
        """提供文本显示组件的默认尺寸建议"""
        return QSize(300, 250)


class SliderComponent(DraggableComponent):
    """滑动条组件"""
    slider_value_changed = Signal(str, int)  # 滑动条ID，值
    
    def __init__(self, component_id, label, min_val, max_val, default_val, unit="", parent=None):
        super().__init__(component_id, parent)
        self.title_label.setText(f"滑动条: {component_id}")
        self.unit = unit  # 添加单位属性
        
        # 设置滑动条组件的最小尺寸
        self.setMinimumSize(400, 170)  # 增加最小宽度
        
        # 确保内容区域足够大
        self.content.setMinimumHeight(100)
        
        # 主容器 - 垂直布局
        main_container = QWidget()
        main_container.setStyleSheet("border: none; background-color: transparent;")
        main_layout = QVBoxLayout(main_container)
        main_layout.setContentsMargins(5, 5, 5, 5)
        main_layout.setSpacing(15)
        
        # 添加标签
        self.label = QLabel(label)
        self.label.setStyleSheet("font-size: 15px; font-weight: bold; color: #333; border: none; padding: 5px;")
        self.label.setAlignment(Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter)
        self.label.setMinimumHeight(25)
        self.label.setMinimumWidth(200)  # 增加标签最小宽度
        self.label.setWordWrap(False)    # 防止标签换行
        main_layout.addWidget(self.label)
        
        # 创建水平布局用于滑动条和值显示
        slider_container = QWidget()
        slider_container.setStyleSheet("border: none; background-color: transparent;")
        slider_container.setMinimumHeight(50)
        slider_layout = QHBoxLayout(slider_container)
        slider_layout.setContentsMargins(5, 0, 5, 0)
        slider_layout.setSpacing(15)
        
        # 添加滑动条 - 增大滑动条尺寸
        self.slider = QSlider(Qt.Orientation.Horizontal)
        self.slider.setMinimum(min_val)
        self.slider.setMaximum(max_val)
        self.slider.setValue(default_val)
        self.slider.setMinimumHeight(40)
        self.slider.setMinimumWidth(230)
        self.slider.setStyleSheet("""
            QSlider::groove:horizontal {
                height: 14px;
                background: #d0d0d0;
                border-radius: 7px;
                margin: 0px;
            }
            QSlider::handle:horizontal {
                background: #0078d7;
                border: 1px solid #0078d7;
                width: 24px;
                height: 24px;
                margin: -5px 0;
                border-radius: 12px;
            }
            QSlider::handle:horizontal:hover {
                background: #1089e8;
            }
        """)
        self.slider.valueChanged.connect(self._on_value_changed)
        slider_layout.addWidget(self.slider, 4)
        
        # 添加值显示 - 增大显示区域和字体
        value_text = f"{default_val}{' ' + unit if unit else ''}"
        self.value_label = QLabel(value_text)
        self.value_label.setMinimumWidth(60)
        self.value_label.setMinimumHeight(35)
        self.value_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.value_label.setStyleSheet("""
            font-size: 18px;
            font-weight: bold;
            color: #0078d7;
            background-color: #f0f0f0;
            border: 1px solid #d0d0d0;
            border-radius: 4px;
            padding: 5px;
            margin: 2px;
        """)
        slider_layout.addWidget(self.value_label, 1)
        
        # 添加滑动条布局到主布局
        main_layout.addWidget(slider_container)
        
        # 添加主容器到内容布局
        self.content_layout.addWidget(main_container)
    
    def _on_value_changed(self, value):
        """滑动条值改变处理"""
        # 添加单位显示
        value_text = f"{value}{' ' + self.unit if self.unit else ''}"
        self.value_label.setText(value_text)
        self.slider_value_changed.emit(self.component_id, value)
    
    def get_value(self):
        """获取滑动条值"""
        return self.slider.value()
    
    def set_value(self, value):
        """设置滑动条值"""
        self.slider.setValue(value)
    
    def sizeHint(self):
        """提供滑动条组件的默认尺寸建议"""
        return QSize(420, 170) 